package com.ruoyi.business.youdaoController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.business.protocol.ask.RtaApiRequestOuterClass;
import com.ruoyi.business.protocol.ask.RtaApiResponseOuterClass;
import com.ruoyi.business.services.HttpService;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.enums.SaveType;
import com.ruoyi.common.utils.EncrypDES;
import com.ruoyi.common.utils.GetUrlParam;
import com.ruoyi.common.utils.OtherUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.domain.vo.R;
import com.ruoyi.system.protocol.IDynamicSearchService;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;

@RestController
@RequestMapping("ownJdApi")
public class JdController {

    @Autowired
    private RedisCache redisCache;
    @Autowired
    private HttpService httpService;

    private final static String CLASSESEN = "youdao";

    //wifi回调地址
    private final static String CALLBACK_URLBASE = "http://c2.wkanx.com/tracking";





    /**
     * https://www.ssptqt.com/ownJdApi/send?channelId=6954839291660288&dmpid=_TS_&idfa=_IDFA_&imeimd5=_IMEI_MD5_&oaid=_OAID_&ip=_IP_&ua=_UA_&timestamp=_TS_&os=_OS_&model=_MODEL_&callback_url=_CALLBACK_URL_
     * @param request
     * @return
     * @throws Exception
     */

    @Log(title = "有道", businessType = BusinessType.ESCALATION, esIndex = "youdao_log", saveType = SaveType.ES)
    @RequestMapping("/send")
    public Object send(HttpServletRequest request) throws Exception {
        String queryString = request.getQueryString();
        String channelId = request.getParameter("channelId");
        String dmpid = request.getParameter("dmpid");
        if(StringUtils.isBlank(channelId) || "null".equals(channelId)){
            return R.failure().msg("channelId不能为空");
        }
        if(StringUtils.isBlank(dmpid) || "null".equals(dmpid)){
            return R.failure().msg("dmpid不能为空");
        }

        Map<String, Object> baseParamsMap = GetUrlParam.queryStrToMap(queryString);

        baseParamsMap.remove("channelId");
        baseParamsMap.remove("dmpid");


        Map<String, Object> channelDetail = redisCache.getCacheMapValue(CLASSESEN+"Cache", channelId);
        if(channelDetail == null){
            return R.failure().msg("channelId不正确");
        }
        String url = channelDetail.get("request_address") + "";
        String requestType = channelDetail.get("request_type") + "";
        String requestAddress = GetUrlParam.getRequestAddress(url);
        String staticParameters = GetUrlParam.TruncateUrlPage(url);
        Map<String, Object> staticParamsMap = GetUrlParam.queryStrToMap(staticParameters);
        baseParamsMap.putAll(staticParamsMap);


        String ua = baseParamsMap.get("ua") + "";
        String ip = baseParamsMap.get("ip") + "";
        if(StringUtils.isNotBlank(ua) && !"null".equals(ua)){
            ua = URLDecoder.decode(ua, Constants.UTF8);
        }else{
            //request 获取 ua
            ua = request.getHeader("User-Agent");
            baseParamsMap.put("ua", URLEncoder.encode(ua, Constants.UTF8));
        }
        if(StringUtils.isNotBlank(ip) && !"null".equals(ip)){
        }else{
            //request 获取 ip
            ip = IpUtils.getIpAddr(request);
        }



        String callbackUrl = URLDecoder.decode(baseParamsMap.get("callback_url") + "", Constants.UTF8);
        String callbackRequestAddress = GetUrlParam.getRequestAddress(callbackUrl);
        String callbackStaticParameters = GetUrlParam.TruncateUrlPage(callbackUrl);
        EncrypDES encrypDES = new EncrypDES();
        String callbackBase = OtherUtils.getServerUrl(request) + "ownJdApi/callback/"+ channelId +"/"+ dmpid +"/";
        String encrypt_u = encrypDES.encrypt(callbackRequestAddress);
        String nu = callbackBase + encrypt_u + "?"+callbackStaticParameters;
        //nu必须是https请求
        nu = nu.replace("http://", "https://");
        //抖音回调地址取得参数是callback
        baseParamsMap.put("callback_url", URLEncoder.encode(nu, Constants.UTF8));

        List<String> tempList = new ArrayList<>();
        for(String key: baseParamsMap.keySet()){
            tempList.add(key+"="+baseParamsMap.get(key));
        }
        String requestParameters = String.join("&", tempList);


        String uuid = IdUtils.fastSimpleUUID();
        String reqType = "click";
        if("POST".equals(requestType)){
            httpService.sendPost(requestAddress, requestParameters, null, ua, uuid, reqType);
        }else{
            httpService.sendGet(requestAddress, requestParameters, null, ua, uuid, reqType);
        }
        return R.success().msg(uuid);
    }


    /**
     * https://www.ssptqt.com/ownJdApi/send2?channelId=6954840741332992&dmpid=__SID__&cid=__CID__&idfa=__PLAIN_IDFA__&idfa_md5=__IDFA__&imeimd5=__PLAIN_IMEI__&oaid=__OAID__&imei=__IMEI__&mac=__MAC__&timestamp=__STIME__&os=__OS__&ip=&ua=
     * wifi->京东
     * @param request
     * @return
     * @throws Exception
     */
    @Log(title = "有道", businessType = BusinessType.ESCALATION, esIndex = "youdao_log", saveType = SaveType.ES)
    @RequestMapping("/send2")
    public Object send2(HttpServletRequest request) throws Exception {
        String queryString = request.getQueryString();
        String channelId = request.getParameter("channelId");
        String dmpid = request.getParameter("dmpid");
        if(StringUtils.isBlank(channelId) || "null".equals(channelId)){
            return R.failure().msg("channelId不能为空");
        }
        if(StringUtils.isBlank(dmpid) || "null".equals(dmpid)){
            return R.failure().msg("dmpid不能为空");
        }

        Map<String, Object> baseParamsMap = GetUrlParam.queryStrToMap(queryString);

        baseParamsMap.remove("channelId");
        baseParamsMap.remove("dmpid");

        Map<String, Object> channelDetail = redisCache.getCacheMapValue(CLASSESEN+"Cache", channelId);
        if(channelDetail == null){
            return R.failure().msg("channelId不正确");
        }
        String url = channelDetail.get("request_address") + "";
        String requestType = channelDetail.get("request_type") + "";
        String requestAddress = GetUrlParam.getRequestAddress(url);
        String staticParameters = GetUrlParam.TruncateUrlPage(url);
        Map<String, Object> staticParamsMap = GetUrlParam.queryStrToMap(staticParameters);
        baseParamsMap.putAll(staticParamsMap);


        String ua = baseParamsMap.get("ua") + "";
        String ip = baseParamsMap.get("ip") + "";
        if(StringUtils.isNotBlank(ua) && !"null".equals(ua)){
            ua = URLDecoder.decode(ua, Constants.UTF8);
        }else{
            //request 获取 ua
            ua = request.getHeader("User-Agent");
            baseParamsMap.put("ua", URLEncoder.encode(ua, Constants.UTF8));
        }
        if(StringUtils.isNotBlank(ip) && !"null".equals(ip)){
        }else{
            //request 获取 ip
            ip = IpUtils.getIpAddr(request);
        }

        String callbackClientId = channelDetail.get("callback_clientid") + "";
        String callbackSecretkey = channelDetail.get("callback_secretkey") + "";

        String idfa = getMapValue(baseParamsMap, "idfa");
        String os = getMapValue(baseParamsMap, "os");




        String oaid = getMapValue(baseParamsMap, "oaid");
        LinkedHashMap<String, String> callbackMap = new LinkedHashMap<>();
        callbackMap.put("cid", getMapValue(baseParamsMap, "cid"));
        callbackMap.put("clientid", callbackClientId);
        callbackMap.put("clientkey", callbackSecretkey);
        callbackMap.put("idfa", idfa);
        callbackMap.put("imei", getMapValue(baseParamsMap, "imei"));
        //下游的mac是进行MD5加密过的就是上游的mac_md5
        callbackMap.put("mac", getMapValue(baseParamsMap, "mac"));
        callbackMap.put("os", os);
        //sid代表请求标识
        callbackMap.put("sid", dmpid);
        //stime为上报时间戳。 上传过来的参数为ts
        callbackMap.put("stime", getMapValue(baseParamsMap, "timestamp"));

        List<String> tempList = new ArrayList<>();
        for(String key: callbackMap.keySet()){
            tempList.add(key+"="+callbackMap.get(key));
        }
        String callbackParams = String.join("&", tempList);
        EncrypDES encrypDES = new EncrypDES();
        String callbackBase = OtherUtils.getServerUrl(request) + "ownJdApi/callback2/"+channelId+"/"+dmpid+"/";
        String encrypt_u = encrypDES.encrypt(CALLBACK_URLBASE);
        String nu = callbackBase + encrypt_u + "?"+callbackParams;

        baseParamsMap.put("os", os.equals("0")?"android":os.equals("1")?"ios":"android");
        baseParamsMap.put("ts", baseParamsMap.get("timestamp")+"000");
        baseParamsMap.put("callback_url", URLEncoder.encode(nu, Constants.UTF8));


        tempList = new ArrayList<>();
        for(String key: baseParamsMap.keySet()){
            tempList.add(key+"="+baseParamsMap.get(key));
        }
        String requestParameters = String.join("&", tempList);

        String uuid = IdUtils.fastSimpleUUID();
        String reqType = "click";
        if("POST".equals(requestType)){
            httpService.sendPost(requestAddress, requestParameters, null, ua, uuid, reqType);
        }else{
            httpService.sendGet(requestAddress, requestParameters, null, ua, uuid, reqType);
        }
        return R.success().msg(uuid);
    }




    private String getMapValue(Map<String, Object> map, String key){
        if(map == null){
            return "";
        }
        if(map.get(key) == null){
            return "";
        }
        return map.get(key)+"";
    }


    @Log(title = "有道", businessType = BusinessType.CALLBACK, esIndex = "youdao_log", saveType = SaveType.ES)
    @RequestMapping("/callback/{channelId}/{dmpid}/{encryptedUrl}")
    public Object callback(HttpServletRequest request, @PathVariable("channelId") String channelId, @PathVariable("encryptedUrl") String encryptedUrl) throws Exception {
        String queryString = request.getQueryString();
        EncrypDES encrypDES = new EncrypDES();
        String requestAddress = encrypDES.decrypt(encryptedUrl);

        String uuid = IdUtils.fastSimpleUUID();
        String reqType = "callback";
        httpService.sendGet(requestAddress, queryString, null, null, uuid, reqType);
        return R.success();
    }


    @Log(title = "有道", businessType = BusinessType.CALLBACK, esIndex = "youdao_log", saveType = SaveType.ES)
    @RequestMapping("/callback2/{channelId}/{dmpid}/{encryptedUrl}")
    public Object callback(HttpServletRequest request, @PathVariable("encryptedUrl") String encryptedUrl) throws Exception {
        String queryString = request.getQueryString();
        Map<String, Object> queryMap = GetUrlParam.queryStrToMap(queryString);
        String eventType = queryMap.get("event_type") + "";
        if("1".equals(eventType)){
            queryMap.put("event_type", 1);
        }else if("2".equals(eventType)) {
            queryMap.put("event_type", 2);
        }else {
            queryMap.put("event_type", 1);
        }


        LinkedHashMap<String, String> callbackMap = new LinkedHashMap<>();
        callbackMap.put("cid", getMapValue(queryMap, "cid"));
        callbackMap.put("clientid", getMapValue(queryMap, "clientid"));

        callbackMap.put("idfa", getMapValue(queryMap, "idfa"));
        //下游没有imei, 但是有imei_md5
        callbackMap.put("imei", getMapValue(queryMap, "imei"));
        //下游的mac是进行MD5加密过的就是上游的mac_md5
        callbackMap.put("mac", getMapValue(queryMap, "mac"));
        callbackMap.put("os", getMapValue(queryMap, "os"));
        //sid是下游给的click_id。 代表请求标识
        callbackMap.put("sid", getMapValue(queryMap, "sid"));
        //stime为上报时间戳。 上传过来的参数为ts
        callbackMap.put("stime", getMapValue(queryMap, "stime"));
        //获取当前时间戳 并转化为秒
        callbackMap.put("ts", (System.currentTimeMillis()/1000)+"");

        String callbackSecretkey = getMapValue(queryMap, "clientkey");
        List<String> tempList = new ArrayList<>();
        for(String key: callbackMap.keySet()){
            tempList.add(key+"="+callbackMap.get(key));
        }
        String callbackParams = String.join("&", tempList);
        String md5 = DigestUtils.md5DigestAsHex((callbackParams+callbackSecretkey).getBytes(Constants.UTF8)).toUpperCase();
        callbackParams = callbackParams + "&event_type="+getMapValue(queryMap, "event_type");
        queryString = callbackParams + "&sign="+md5;

        EncrypDES encrypDES = new EncrypDES();
        String requestAddress = encrypDES.decrypt(encryptedUrl);

        String uuid = IdUtils.fastSimpleUUID();
        String reqType = "callback";
        httpService.sendGet(requestAddress, queryString, null, null, uuid, reqType);
        return R.success();
    }


    @Autowired
    private IDynamicSearchService dynamicSearchService;

    @RequestMapping("/chulishuju")
    public String chulishuju() {

        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termQuery("url.keyword", "https://api.kumob.cn/ad/api/jdclickInfo"));


        HashMap<String, Object> reqResult = dynamicSearchService.search("req_result", boolQueryBuilder, null, null, null, null, 1, 500);
        List<Map<String, Object>> list = (List<Map<String, Object>>) reqResult.get("data");
        for (Map<String, Object> stringObjectMap : list) {
            String reportResultsStr = stringObjectMap.get("reportResultsStr") + "";
            JSONObject jsonObject = JSON.parseObject(reportResultsStr);
            if("-1".equals(jsonObject.getString("code"))){
                String url = stringObjectMap.get("url")+"";
                String param = stringObjectMap.get("param")+"";
                System.out.println(url+"?"+param);
                String res = HttpUtils.sendGet(url, param, null, null);
                System.out.println(res);
            }
        }

        return "1";
    }


}
